//
//  MMWDHPhotoBrowser.m
//  MMWPT
//
//  Created by 高得华 on 2018/12/12.
//  Copyright © 2018年 高得华. All rights reserved.
//

#import "MMWDHPhotoBrowser.h"
#if __has_include(<AFNetworking/AFNetworking-umbrella.h>)
#import <AFNetworking/AFNetworking-umbrella.h>
#else
#import "AFNetworking-umbrella.h"
#endif
#import "GEdwardInfoController.h"
#import "GEdwardJTOAPPInter.h"
#import "LFAssetManager+SaveAlbum.h"
#import "LFVideoEditingController.h"
#import "LFResultObject_property.h"
#import "UIViewController+HUD.h"

#if __has_include("MDHPT/MDHPT-Swift.h")
#import "MDHPT/MDHPT-Swift.h"
#else
#import "JSTech-Swift.h"
#endif

#import "LFPhotoBrowser.h"
#import "LFAssetManager.h"
#import "HXPhotoPicker.h"
#import "LFPhotoEditingController.h"

#import "HQImageEditViewController.h"
#import "UIImage+GIF.h"
#import "UIImage+LF_Format.h"
#import "LFAssetManager.h"

NSString * const kMMWDHPhotoBrowserFileListTempExtension = @".tmp";
NSString * const kMMWDHPhotoBrowserPhotoBrower = @"kMMWDHPhotoBrowserPhotoBrower";
NSString * const kMMWDHPhotoBrowserSaveImageFailureReason = @"图片需要下载完成";
NSString * const kMMWDHPhotoBrowserSaveImageSuccessMessage = @"^_^ 保存成功!!";
NSString * const kMMWDHPhotoBrowserSaveImageFailureMessage = @"/(ㄒoㄒ)/~~ 保存失败!!";

/** 单例 */
const NSMutableDictionary * downloadDicts;


//MARK: 选择 图片 、 视频的属性类
@interface MMWDHPhotoBrowserSelectModel ()
@end
@implementation MMWDHPhotoBrowserSelectModel

- (instancetype)init {
    if (self = [super init]) {
        self.allow    = kMMWDHPhotoBrowserSelectEnumDefault;
        self.maxCount = 1;
        self.preview  = true;
        self.maxVideoDuration = 120;
        self.maxRecordDuration = 15;
    }
    return self;
}

//MARK: - ===== 20190419 改版 ===== -
///图片/视频选择器的管理者
- (HXPhotoManager *)manager
{
    if (!_manager) {
        _manager = [[HXPhotoManager alloc] initWithType:HXPhotoManagerSelectedTypePhoto];
        //视频最大选择数 默认1 - 必填
        _manager.configuration.videoMaxNum = 1;
        ///视频最大选择数 默认1 - 必填
        _manager.configuration.photoMaxNum = 1;
        ///删除临时的照片/视频 -
        _manager.configuration.deleteTemporaryPhoto = false;
        ///是否开启查看LivePhoto功能呢 - 默认 NO
        _manager.configuration.lookLivePhoto = true;
        ///拍摄的 照片/视频 是否保存到系统相册  默认NO
        _manager.configuration.saveSystemAblum = true;
        ///图片和视频是否能够同时选择 默认 NO
        _manager.configuration.selectTogether = false;
        ///照片列表是否按照片日期排序  默认YES
        _manager.configuration.creationDateSort = true;
        //_manager.configuration.supportRotation = NO;
        //_manager.configuration.cameraCellShowPreview = NO;
        
        ///相册列表每行多少个照片 默认4个 iphone 4s / 5  默认3个
        //_manager.configuration.rowCount = 3;
        ///下载iCloud上的资源  默认YES
        _manager.configuration.downloadICloudAsset = true;
        ///是否需要显示日期section  默认YES
        _manager.configuration.showDateSectionHeader = false;
        ///照片列表倒序 默认 NO
        _manager.configuration.reverseDate = false;
        //是否隐藏原图按钮  默认 NO
        _manager.configuration.hideOriginalBtn = false;
        //是否过滤iCloud上的资源 默认NO
        _manager.configuration.filtrationICloudAsset = false;
        ///是否打开相机功能
        _manager.configuration.openCamera = true;
        
        ///导航 等 的颜色
        _manager.configuration.themeColor = kColor_MDH8976CA();//kColor_MDHTheme();
        _manager.configuration.navBarBackgroudColor = [UIColor blackColor];
        _manager.configuration.navigationTitleColor = [UIColor blackColor];//[UIColor whiteColor];
        _manager.configuration.navigationBar = ^(UINavigationBar *navigationBar, UIViewController *viewController) {
            //[navigationBar setBackgroundImage:[UIImage imageNamed:@"APPCityPlayer_bannerGame"] forBarMetrics:UIBarMetricsDefault];
            //navigationBar.barTintColor = [UIColor redColor];
        };
        //_manager.configuration.sectionHeaderTranslucent = NO;
        //_manager.configuration.navBarBackgroudColor = [UIColor redColor];
        //_manager.configuration.sectionHeaderSuspensionBgColor = [UIColor redColor];
        //_manager.configuration.sectionHeaderSuspensionTitleColor = [UIColor whiteColor];
        //_manager.configuration.statusBarStyle = UIStatusBarStyleLightContent;
        //_manager.configuration.selectedTitleColor = [UIColor redColor];
        
        //_manager.configuration.requestImageAfterFinishingSelection = YES;
        //__weak typeof(self) weakSelf = self;
        _manager.configuration.photoListBottomView = ^(HXPhotoBottomView *bottomView) {
            //bottomView.bgView.barTintColor = weakSelf.bottomViewBgColor;
        };
        _manager.configuration.previewBottomView = ^(HXPhotoPreviewBottomView *bottomView) {
            //bottomView.bgView.barTintColor = weakSelf.bottomViewBgColor;
        };
        _manager.configuration.albumListCollectionView = ^(UICollectionView *collectionView) {
            //NSSLog(@"albumList:%@",collectionView);
        };
        _manager.configuration.photoListCollectionView = ^(UICollectionView *collectionView) {
            //NSSLog(@"photoList:%@",collectionView);
        };
        _manager.configuration.previewCollectionView = ^(UICollectionView *collectionView) {
            //NSSLog(@"preview:%@",collectionView);
        };
        //_manager.configuration.movableCropBox = YES;
        //_manager.configuration.movableCropBoxEditSize = YES;
        //_manager.configuration.movableCropBoxCustomRatio = CGPointMake(1, 1);
        
        //_manager.shouldSelectModel = ^NSString *(HXPhotoModel *model) {
        //// 如果return nil 则会走默认的判断是否达到最大值
        ////return nil;
        //return @"Demo1 116 - 120 行注释掉就能选啦~\(≧▽≦)/~";
        //};
        _edit = [MDHPhotoVideoEditManager manager:_manager];
    }
    return _manager;
}
///编辑者
- (MDHPhotoVideoEditManager *)edit {
    if (!_edit) {
        _edit = [MDHPhotoVideoEditManager manager:self.manager];
    }
    return _edit;
}

@end



@interface MMWDHPhotoBrowser ()
<
LFPhotoBrowserDelegate,
LFPhotoBrowserDownloadDelegate,
HQImageEditViewControllerDelegate
>


//,
//LFPhotoEditingControllerDelegate,
//LFVideoEditingControllerDelegate

/*
 NSMapTable 是在 NSDictionary 之后的一个可变集合模型化的类，它们具有以下区别：
 1. 主要的差别是 NSMapTable 会在集合里的对象被回收的时候删除此对象来保持对键 和/或 值保持“弱引用”；
 2. 当 NSMapTable 添加一个键值对的时候其键或值可以被复制，也可以使用指针标识来进行相等和散列判断；
 3. NSMapTable 可以包含任意指针（其内容不被约束为对象）。
 
 你可以将 NSMapTable 实例配置为对任意指针进行操作，而不仅仅是对象，尽管通常会鼓励使用 C 的 API： void * 指针来操作。 （有关详细信息，请参阅管理映射表）基于对象的 API（例如 setObject：forKey :)将无法在不进行类型转换的情况下对无对象指针操作。
 */
@property (nonatomic, strong) NSMapTable * mapTable;
///展示视图
@property (nonatomic, strong) LFPhotoBrowser *pbVC;
///裁剪的block 回调
@property (nonatomic, copy) void(^blockCutImage)(UIImage * image);

@end

@implementation MMWDHPhotoBrowser

static MMWDHPhotoBrowser * _instance = nil;

+ (void)free:(MMWDHPhotoBrowserSelectModel *)model {
    if (model) {
        [model.manager removeAllTempList];
        model.manager = nil;
    }
    [_instance.mapTable removeAllObjects];
    _instance.mapTable = nil;
    _instance = nil;
}

///单例
+ (MMWDHPhotoBrowser *)shared {
    if (_instance == nil) {
        _instance = [[self alloc] init];
    }
    return _instance;
    /*static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        _instance = [[super allocWithZone:NULL] init] ;
        //不是使用alloc方法，而是调用[[super allocWithZone:NULL] init]
        //已经重载allocWithZone基本的对象分配方法，所以要借用父类（NSObject）的功能来帮助出处理底层内存分配的杂物
    });
    return _instance;*/
}
//+(id)allocWithZone:(struct _NSZone *)zone {
//    return [MMWDHPhotoBrowser shared] ;
//}
//- (id) copyWithZone:(struct _NSZone *)zone {
//    return [MMWDHPhotoBrowser shared];
//}
- (instancetype)init {
    if (self = [super init]) {
        self.mapTable = [NSMapTable weakToWeakObjectsMapTable];
    }
    return self;
}


//MARK: 展示照片
/**
 展示视图
 
 @param items 视频、图片地址 图片
 @param index 选中的哪个
 */
- (void)showPhoto:(NSArray *)items index:(NSInteger)index {
    @autoreleasepool {
        @weakify(self);
        NSArray * arr = [self PhotoInfos:items];
        LFPhotoBrowser *pbVC = [[LFPhotoBrowser alloc] initWithImageArray:arr currentIndex:(int)index];
        pbVC.animatedTime = 0.25f;
        pbVC.delegate = self;
        pbVC.downloadDelegate = self;
        pbVC.isNeedPageControl = arr.count > 1;
        pbVC.isWeaker = true;
        pbVC.canPullDown = true;
        self.pbVC = pbVC;
        [self.mapTable setObject:pbVC forKey:kMMWDHPhotoBrowserPhotoBrower];
        [pbVC showPhotoBrowser];
        pbVC.dismissBlock = ^{
            @strongify(self);
            [self.mapTable removeObjectForKey:kMMWDHPhotoBrowserPhotoBrower];
            self.pbVC = nil;
            [MMWDHPhotoBrowser free:nil];
        };
    }
}

//MARK: - LFPhotoBrowserDelegate 保存等操作
- (CGRect)photoBrowserTargetFrameWithIndex:(int)index key:(NSString *)key
{
    return CGRectZero;
}

/** 设置长按列表 */
- (NSArray <LFPhotoSheetAction *>*)photoBrowserLongPressActionItems:(LFPhotoBrowser *)photoBrowser photoInfo:(LFPhotoInfo *)photoInfo object:(id /* UIImage * /NSURL * */)object
{
    return [self ActionPhotoInfo:photoInfo];
}
/** 设置保存按钮（右下角） */
- (void)photoBrowserSavePreview:(LFPhotoBrowser *)photoBrowser photoInfo:(LFPhotoInfo *)photoInfo object:(id /* UIImage * /NSURL * */)object {
    [self buttonSaveImageActionPhotoInfo:photoInfo];
}

- (NSMutableArray <LFPhotoSheetAction *> *)ActionPhotoInfo:(LFPhotoInfo *)photoInfo {
    @weakify(self);
    LFPhotoSheetAction *action1 = [LFPhotoSheetAction actionWithTitle:@"保存图片" style:LFPhotoSheetActionType_Default handler:^(id object) {
        @strongify(self);
        [self buttonSaveImageActionPhotoInfo:photoInfo];
    }];
    
    LFPhotoSheetAction *action2 = [LFPhotoSheetAction actionWithTitle:@"取消" style:LFPhotoSheetActionType_Cancel handler:^(id object) {
        
    }];
    
    NSString * urlQRCode = photoInfo.urlQRCode;
    if (urlQRCode && ![urlQRCode containsString:@"weixin"] && ![urlQRCode containsString:@"wechat"]) {
        LFPhotoSheetAction *action3 = [LFPhotoSheetAction actionWithTitle:@"识别图中二维码" style:LFPhotoSheetActionType_Default handler:^(id object) {
            //@strongify(self);
            if ([urlQRCode hasPrefix:@"http"]) {
                [GEdwardJTOAPPInter GESharedSafari:urlQRCode];
                /*if ([urlQRCode containsString:@".wechat.com"]) {
                    [[UIApplication sharedApplication] openURL:[NSURL URLWithString:[@"weixin://scanqrcode" stringByAppendingFormat:@"?%@",urlQRCode]]];
                }
                else if ([urlQRCode containsString:@".qq.com"]) {
                    [GEdwardJTOAPPInter GESharedSafari:urlQRCode];
                }
                else{
                    [GEdwardJTOAPPInter GESharedSafari:urlQRCode];
                    //self.pbVC.dismissBlock = ^{};
                    //[[AppDelegate sharedAppDelegate] pushToH5Vc:photoInfo.urlQRCode title:@"" data:@{@"viewStyle": @"-2"}];
                }*/
            }else{
                AlertViewShowR(urlQRCode, @"粘贴", ^(int index) {
                    if (index == 2) {
                        ///UIPasteboard 这个就是剪贴板
                        [UIPasteboard generalPasteboard].string = urlQRCode;
                        ShowHUDMesHidden(@"粘贴成功~", [MDHRouter sharedInstance].navigationControllerStack.topViewController.view);
                    }
                });
            }
        }];
        return @[action1, action2, action3,].mutableCopy;
    }
    return @[action1, action2, ].mutableCopy;
}


/** 设置更多按钮（右上角） */
- (void)photoBrowserMorePreview:(LFPhotoBrowser *)photoBrowser photoInfo:(LFPhotoInfo *)photoInfo object:(id /* UIImage * /NSURL * */)object {
    [photoBrowser ShowPhotoBrowserRightTopBtn:[self ActionPhotoInfo:photoInfo] object:object];
}

#warning 注释以下方法，视频则为在线播放
//MARK: - LFPhotoBrowserDownloadDelegate 下载的操作
-(void)photoBrowser:(LFPhotoBrowser *)photoBrowser downloadVideoWithPhotoInfo:(LFPhotoInfo *)photoInfo
{
    __weak typeof(self) weakSelf = self;
    NSString *path = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask,YES) objectAtIndex:0] stringByAppendingPathComponent:photoInfo.videoUrl.lastPathComponent];
    
    /** 测试下载失败 */
    //    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.f * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
    //        photoInfo.downloadFail = YES;
    //        [photoBrowser reloadView:photoInfo];
    //    });
    //
    //
    //    return;
    
    NSString *tempPath = [self getDLTempPathWithSavePath:path];
    signed long long fileSize = 0;
    NSFileManager *fileManager = [NSFileManager new]; // default is not thread safe
    if ([fileManager fileExistsAtPath:tempPath]) {
        NSError *error = nil;
        NSDictionary *fileDict = [fileManager attributesOfItemAtPath:tempPath error:&error];
        if (!error && fileDict) {
            fileSize = [fileDict fileSize];
        }
    }
    
    /** 获取原下载路径续传 */
    [self basicHttpFileDownloadWithUrlString:photoInfo.videoUrl offset:fileSize params:@{} timeout:5.f savePath:path download:^(long long totalBytes, long long totalBytesExpected) {
        
        LFPhotoInfo *b_phtoInfo = [weakSelf.mapTable objectForKey:photoInfo.videoUrl];
        b_phtoInfo.downloadProgress = (float)(totalBytes*1.0/totalBytesExpected);
        
    } success:^{
        
        LFPhotoInfo *b_phtoInfo = [weakSelf.mapTable objectForKey:photoInfo.videoUrl];
        b_phtoInfo.videoPath = path;
        LFPhotoBrowser *pb = [weakSelf.mapTable objectForKey:kMMWDHPhotoBrowserPhotoBrower];
        [pb reloadView:b_phtoInfo];
        
    } failure:^(NSError *error) {
        
        LFPhotoInfo *b_phtoInfo = [weakSelf.mapTable objectForKey:photoInfo.videoUrl];
        /** 更新Model状态 */
        b_phtoInfo.downloadFail = YES;
        LFPhotoBrowser *pb = [weakSelf.mapTable objectForKey:kMMWDHPhotoBrowserPhotoBrower];
        [pb reloadView:b_phtoInfo];
    }];
}


//MARK: - 将相片存入相册, 只回调这个方法
///将图片保存到相册
- (void)saveALAssetsLibrary:(UIImage * _Nullable)image block:(VoidBlock_int _Nullable)block {
    @autoreleasepool {
        @weakify(self);
        if (image == nil) {
            DTLog(@"保存的图片为空----");
            ShowHUDMesHidden(kMMWDHPhotoBrowserSaveImageFailureMessage, self.pbVC.view);
            if (block != nil) {
                block(0);
            }
            [MMWDHPhotoBrowser free:nil];
            return;
        }
        GEdwardInfoController * info = [GEdwardInfoController sharedInstance];
        NSString * albuName = @"APP相册";
        if (info.CFBundleDisplayName.length > 0) {
            albuName = info.CFBundleDisplayName;
        }
        [[LFAssetManager manager] saveImageToCustomPhotosAlbumWithTitle:albuName images:@[image] complete:^(NSArray<id> *assets, NSError *error) {
            [MDHFileConstant mainAsyncSafe:^{
                @strongify(self);
                BOOL is_ok = (assets && !error);
                if (is_ok) {
                    ShowHUDMesHidden(kMMWDHPhotoBrowserSaveImageSuccessMessage, self.pbVC.view);
                }else{
                    ShowHUDMesHidden(kMMWDHPhotoBrowserSaveImageFailureMessage, self.pbVC.view);
                }
                if (block != nil) {
                    block(is_ok ? 1:0);
                }
            }];
        }];
    }
}
- (void)saveALAssetsLibrary:(UIImage * _Nullable)image {
    [self saveALAssetsLibrary:image block:nil];
}

//MARK: ====== 常用函数 ======
- (NSString *)getDLTempPathWithSavePath:(NSString *)path {
    NSString *tempPath = [path stringByAppendingString:kMMWDHPhotoBrowserFileListTempExtension];
    return tempPath;
}

- (BOOL)isExistsDL:(NSString *)url {
    return [downloadDicts objectForKey:url];
}

- (void)cancelDL:(NSString *)url {
    NSURLSessionDataTask *operation = [downloadDicts objectForKey:url];
    [operation cancel];
}

///取消
- (void)cancelAllDL {
    [downloadDicts enumerateKeysAndObjectsUsingBlock:^(NSString *  _Nonnull key, id  _Nonnull obj, BOOL * _Nonnull stop) {
        [self cancelDL:key];
    }];
}

///下载接口
- (void)basicHttpFileDownloadWithUrlString:(NSString*)aUrlString
                                    offset:(u_int64_t)offset
                                    params:(NSDictionary*)aParams
                                   timeout:(NSTimeInterval)timeout
                                  savePath:(NSString*)aSavePath
                                  download:(GEdwardLFPBCDownloadBlock)aDownload
                                   success:(GEdwardLFPBCSuccessBlock)aSuccess
                                   failure:(GEdwardLFPBCFailureBlock)aFailure {
    
    if (downloadDicts == nil) {
        downloadDicts = [@{} mutableCopy];
    }
    
    if ([self isExistsDL:aUrlString]) return;
    
    NSString *tempPath = [aSavePath stringByAppendingString:kMMWDHPhotoBrowserFileListTempExtension]; // 临时保存路径
    
    AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
    manager.requestSerializer = [AFHTTPRequestSerializer serializer];
    
    NSMutableURLRequest *request = [manager.requestSerializer requestWithMethod:@"GET" URLString:aUrlString parameters:aParams error:nil];
    request.timeoutInterval = (timeout <= 0 ? 15.f : timeout);
    [request setValue:@"gzip, deflate" forHTTPHeaderField:@"Accept-Encoding"];
    [request setCachePolicy:NSURLRequestReloadIgnoringCacheData]; // 忽略本地缓存重新下载
    if (offset>0) {
        NSMutableURLRequest *mutableURLRequest = [request mutableCopy];
        [mutableURLRequest setValue:[NSString stringWithFormat:@"bytes=%llu-", offset] forHTTPHeaderField:@"Range"];
        request = mutableURLRequest;
    }
    
    manager.securityPolicy.allowInvalidCertificates = YES;
    manager.securityPolicy.validatesDomainName = NO;
    
    NSURLSessionDataTask * task = [manager GET:aUrlString parameters:aParams headers:nil progress:^(NSProgress * _Nonnull downloadProgress) {
        if (aDownload) {
            aDownload(downloadProgress.completedUnitCount, downloadProgress.totalUnitCount);
        }
    } success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
        [downloadDicts removeObjectForKey:aUrlString];
        NSError *err;
        NSFileManager *fileManager = [NSFileManager new];
        [fileManager moveItemAtPath:tempPath toPath:aSavePath error:&err];
        
        NSError *error = nil;
        if (error && aFailure)
            aFailure(error);
        else if (aSuccess)
            aSuccess();
        
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
        [downloadDicts removeObjectForKey:aUrlString];
        if (aFailure) aFailure(error);
    }];
    
    [downloadDicts setObject:task forKey:aUrlString];
}

///下载网址的 Library
- (void)downloadWithUrl:(NSString *)url {
    LFPhotoInfo * info = [LFPhotoInfo new];
    info.originalImageUrl = url;
    [self buttonSaveImageActionPhotoInfo:info];
}

//MARK: 私有函数
///下载、保存图片
- (void)buttonSaveImageActionPhotoInfo:(LFPhotoInfo *)items {
    if([items.originalImageUrl hasPrefix:@"http"]) { // 图片 -> 如果是网络图片
        NSURL * url = [NSURL URLWithString:items.originalImageUrl];
        [[SDWebImageManager sharedManager] loadImageWithURL:url options:SDWebImageRefreshCached progress:nil completed:^(UIImage * _Nullable image, NSData * _Nullable data, NSError * _Nullable error, SDImageCacheType cacheType, BOOL finished, NSURL * _Nullable imageURL) {
            if (image) {
                [self saveALAssetsLibrary:image];
            }else{
                ShowHUDMesHidden(kMMWDHPhotoBrowserSaveImageFailureReason, self.pbVC.view);
            }
        }];
    }else{ // 如果是本地图片
        [self saveALAssetsLibrary:items.originalImage];
    }
}

///将传入的数据进行转化
- (NSArray <LFPhotoInfo *> *)PhotoInfos:(NSArray *) infos {
    NSMutableArray *items = [NSMutableArray arrayWithCapacity:infos.count];
    int count = 0, max = 2;
    for (id item in infos) {
        if ([item isKindOfClass:[UIImage class]]) {
            LFPhotoInfo *photo = [LFPhotoInfo photoInfoWithType:PhotoType_image key:nil];
            photo.originalImage = item;
            [items addObject:photo];
            continue;
        }
        if ([item isKindOfClass:[NSString class]]) {
            NSString * url = (NSString *)item;
            if ([url hasSuffix:@".mp4"]) {
                LFPhotoInfo *photo = [LFPhotoInfo photoInfoWithType:PhotoType_video key:nil];
                if (count++ < max) {
                    photo.isNeedSlider = YES;
                }
                photo.isAutoPlay = YES;
                photo.videoPath = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask,YES) objectAtIndex:0] stringByAppendingPathComponent:url.lastPathComponent];
                photo.videoUrl = url;
                photo.isLoading = [self isExistsDL:url];
                [items addObject:photo];
                
                [self.mapTable setObject:photo forKey:url];
            } else {
                if (url.length > 0) {
                    LFPhotoInfo *photo = [LFPhotoInfo photoInfoWithType:PhotoType_image key:nil];
                    photo.originalImageUrl = url;
                    [items addObject:photo];
                }
                /** 图片是内置SD下载，没有必要记录数据源 */
                //[self.mapTable setObject:photo forKey:url];
            }
        }else{
            if (item) {
                [items addObject:item];
            }
        }
    }
    return items.copy;
}

//MARK: - ===== 20190419 改版 ===== - 选择图片及视频
- (void)showBrowser:(MMWDHPhotoBrowserSelectModel *)model block:(void(^)(NSArray <HXPhotoModel *>*))block {
    @autoreleasepool {
        if (model == nil) {
            [MMWDHPhotoBrowser free:model];
            return;
        }
        
        UIViewController * topVc = [MDHRouter sharedInstance].navigationControllerStack.topViewController;
        ///返回数据
        void(^blockCancelPvData)(void) = ^{
            DTLog(@"取消了");
            //ShowHUDMesHidden(@"取消选择图片/视频~", topVc.view);
            if (block) {
                block([NSArray new]);
            }
            [MMWDHPhotoBrowser free:model];
        };
        HXPhotoManager * manager_ = model.manager;
        
        //__weak typeof(self) weakSelf = self;
        ///设置图片的配置
        void(^blockSetPhotoPz)(void) = ^{
            manager_.configuration.photoMaxNum = model.maxCount;
        };
        ///设置视频的配置
        void(^blockSetVideoPz)(void) = ^{
            manager_.configuration.videoMaxNum = model.maxCount;
            ///视频能选择的最大秒数  -  默认 3分钟/180秒
            manager_.configuration.videoMaximumSelectDuration = model.maxVideoDuration;
            ///视频能选择的最小秒数  -  默认 0秒 - 不限制
            manager_.configuration.videoMinimumSelectDuration = 0;
            ///相机视频录制最大秒数  -  默认60s
            manager_.configuration.videoMaximumDuration = model.maxRecordDuration;
        };
        
        ///允许选择的类型
        switch (model.allow) {
            case kMMWDHPhotoBrowserSelectEnumDefault:///图片视频共存
            {
                manager_.type = HXPhotoManagerSelectedTypePhotoAndVideo;
                blockSetVideoPz();
                blockSetPhotoPz();
            }
                break;
            case kMMWDHPhotoBrowserSelectEnumPhoto:
            {
                manager_.type = HXPhotoManagerSelectedTypePhoto;
                blockSetPhotoPz();
            }
                break;
            case kMMWDHPhotoBrowserSelectEnumVideo:
            {
                manager_.type = HXPhotoManagerSelectedTypeVideo;
                blockSetVideoPz();
            }
                break;
            default:
                break;
        }
        
        @weakify(self);
        ///进行转化数据
        void(^blockTransModel)(NSArray<HXPhotoModel *> *allList) = ^(NSArray<HXPhotoModel *> *allList){
            @strongify(self);
            [self transModel:allList manager:model block:block];
        };
        
        ///进入选择相册的界面
        void(^blockEnterSelectPhoto)(void) = ^{
            [topVc hx_presentSelectPhotoControllerWithManager:manager_ didDone:^(NSArray<HXPhotoModel *> *allList, NSArray<HXPhotoModel *> *photoList, NSArray<HXPhotoModel *> *videoList, BOOL isOriginal, UIViewController *viewController, HXPhotoManager *manager) {
                if (videoList.count > 0) {
                    HXPhotoModel * model = videoList.firstObject;
                    if ([model.fileURL.absoluteString hasSuffix:@"mp4"]) {
                        blockTransModel(allList);
                    }else{
                        [[LFAssetManager manager] getVideoResultWithAsset:model.asset completion:^(LFResultVideo *resultVideo) {
                            if (resultVideo.url != nil) {
                                model.fileURL = resultVideo.url;
                            }
                            if (resultVideo.coverImage != nil) {
                                model.previewPhoto = resultVideo.coverImage;
                            }
                            blockTransModel(@[model]);
                        }];
                    }
                }else{
                    blockTransModel(allList);
                }
            } cancel:^(UIViewController *viewController, HXPhotoManager *manager) {
                blockCancelPvData();
            }];
        };
        
        if (model.isCamera) {///是否相机显示
            if(![UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]) {
                [topVc.view hx_showImageHUDText:@"此设备不支持相机!"];
                [MMWDHPhotoBrowser free:model];
                return;
            }
            [topVc hx_presentCustomCameraViewControllerWithManager:manager_ done:^(HXPhotoModel *model, HXCustomCameraViewController *viewController) {
                if (model) {
                    [manager_ afterListAddCameraTakePicturesModel:model];
                    if (model.type == HXPhotoModelMediaTypeVideo) {
                        [[LFAssetManager manager] getVideoResultWithAsset:model.asset completion:^(LFResultVideo *resultVideo) {
                            if (resultVideo.url != nil) {
                                model.fileURL = resultVideo.url;
                            }
                            if (resultVideo.coverImage != nil) {
                                model.previewPhoto = resultVideo.coverImage;
                            }
                            blockTransModel(@[model]);
                        }];
                    }else{
                        [[LFAssetManager manager] getPhotoWithAsset:model.asset isOriginal:true completion:^(LFResultImage *resultImage) {
                            if (model.previewPhoto != nil) {
                                model.previewPhoto = resultImage.originalImage;
                            }
                            blockTransModel(@[model]);
                        }];
                    }
                }else{
                    blockCancelPvData();
                }
            } cancel:^(HXCustomCameraViewController *viewController) {
                if (viewController.enterStyle == 2) {
                    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
                        blockEnterSelectPhoto();
                    });
                }else{
                    blockCancelPvData();
                }
            }];
        }else{///显示相册
            blockEnterSelectPhoto();
        }
    }

}

//进行转化
- (void)transModel:(NSArray<HXPhotoModel *> *)allList manager:(MMWDHPhotoBrowserSelectModel * _Nullable)model block:(void(^)(NSArray <HXPhotoModel *>*))block {
    @autoreleasepool {
        //HXPhotoManager * manager_ = model.manager;
        ShowHUDMessageView(nil);
        NSMutableArray *resultArray = [NSMutableArray array];
        
        for (NSInteger i = 0; i < allList.count; i++) { [resultArray addObject:@1];}
        
        @weakify(self);
        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
            @strongify(self);
            if (allList.count > 0) {
                void (^photosComplete)(HXPhotoModel *, NSInteger) = ^(HXPhotoModel *result, NSInteger index) {
                    if (result) [resultArray replaceObjectAtIndex:index withObject:result];
                    
                    if ([resultArray containsObject:@1]) return;
                    
                    dispatch_main_async_safe(^{
                        if (self == nil) return ;
                        DismissHud(nil);
                        [LFAssetManager free];
                        [MMWDHPhotoBrowser free:model];
                        if (block) {
                            block(allList);
                        }
                    });
                };
                
                for (NSInteger i = 0; i < allList.count; i++) {
                    HXPhotoModel *model = allList[i];
                    model.tempAsset = nil;
                    if (model.type == HXPhotoModelMediaTypePhoto) {
                        UIImage * image = nil;
                        if (model.previewPhoto) {
                            image = model.previewPhoto;
                        }else if (model.thumbPhoto) {
                            image = model.thumbPhoto;
                        }else if (model.tempImage) {
                            image = model.tempImage;
                        }
                        model.previewPhoto = image;
                        if (model.previewPhoto) {
                            photosComplete(model, i);
                        }else{
                            [model requestImageWithResultHandler:^(UIImage * _Nullable result, NSDictionary * _Nullable info) {
                                model.previewPhoto = result;
                                photosComplete(model, i);
                            }];
                        }
                    }else if (model.type == HXPhotoModelMediaTypePhotoGif) {
                        @weakify(self);
                        PHImageManager * imageManager = [PHImageManager defaultManager];
                        [imageManager requestImageDataForAsset:model.asset options:0 resultHandler:^(NSData * _Nullable imageData, NSString * _Nullable dataUTI, UIImageOrientation orientation, NSDictionary * _Nullable info) {
                            @strongify(self);
                            if (imageData) {
                                UIImage * image = [UIImage sd_animatedGIFWithData:imageData];
                                model.previewPhoto = image;
                                model.tempAsset = imageData;
                                photosComplete(model, i);
                            }
                         }];
                    }else if (model.type == HXPhotoModelMediaTypeLivePhoto) {
                        if (@available(iOS 9.1, *)) {
                            [model requestLivePhotoWithSize:CGSizeZero startRequestICloud:nil progressHandler:nil success:^(PHLivePhoto * _Nullable livePhoto, HXPhotoModel * _Nullable model, NSDictionary * _Nullable info) {
                                
                                NSString *fileName = [model.asset valueForKey:@"filename"];
                                
                                NSString *fileFirstName = [fileName stringByDeletingPathExtension];
                                
                                NSArray *resourceArray = [PHAssetResource assetResourcesForLivePhoto:livePhoto];
                                PHAssetResourceManager *arm = [PHAssetResourceManager defaultManager];
                                PHAssetResource *assetResource = resourceArray.lastObject;
                                NSString *cache = [LFAssetManager CacheVideoPath];
                                NSString *filePath = [cache stringByAppendingPathComponent:[fileFirstName stringByAppendingPathExtension:@"mov"]];
                                BOOL isExists = [[NSFileManager defaultManager] fileExistsAtPath:filePath];
                                
                                NSURL *videoURL = [[NSURL alloc] initFileURLWithPath:filePath];
                                
                                void (^livePhotoToGif)(NSURL *) = ^(NSURL *videoURL) {
                                    [LFToGIF optimalGIFfromURL:videoURL loopCount:0 completion:^(NSURL *GifURL) {
                                        if (GifURL) {
                                            /** 图片数据 */
                                            NSData *imageData = [NSData dataWithContentsOfURL:GifURL];
                                            /** 原图 */
                                            UIImage *source = [UIImage LF_imageWithImageData:imageData];
                                            model.previewPhoto = source;
                                            model.tempAsset = imageData;
                                            photosComplete(model, i);
                                        }
                                    }];
                                };
                                
                                if (isExists) {
                                    livePhotoToGif(videoURL);
                                } else {
                                    [arm writeDataForAssetResource:assetResource toFile:videoURL options:nil completionHandler:^(NSError * _Nullable error)
                                     {
                                        if (error) {
                                            [[LFAssetManager manager] getPhotoWithAsset:model.asset completion:^(UIImage *photo, NSDictionary *info, BOOL isDegraded) {
                                                model.previewPhoto = photo;
                                                photosComplete(model, i);
                                            }];
                                        } else {
                                            livePhotoToGif(videoURL);
                                        }
                                    }];
                                }
                                
                            } failed:^(NSDictionary * _Nullable info, HXPhotoModel * _Nullable model) {
                                photosComplete(model, i);
                            }];
                        } else {
                            // Fallback on earlier versions
                        }
                    }else{
                        photosComplete(model, i);
                    }
                }
            }else{
                if (block) {
                    block(allList);
                }
                DismissHud(nil);
                [MMWDHPhotoBrowser free:model];
            }
        });
    }
}


///对单张图片进行剪切
- (void)cutIntoPhoto:(UIImage *)image block:(void(^)(UIImage *))block {
    if (image == nil || CGSizeEqualToSize(image.size, CGSizeZero)) {
        return;
    }
    HXPhotoModel * model = [HXPhotoModel new];
    model.previewPhoto = image;
    [self cutIntoPhotoAsset:model block:block];
}

///对单张图片进行剪切
- (void)cutIntoPhotoAsset:(HXPhotoModel *)model block:(void(^)(UIImage *))block {
    @autoreleasepool {
        self.blockCutImage = block;
        
        HQImageEditViewController * vc = [HQImageEditViewController new];
        vc.modelOrigin = model;
        vc.originImage = model.previewPhoto;
        vc.delegate = self;
        vc.maskViewAnimation = true;
        vc.modalPresentationStyle = UIModalPresentationOverFullScreen;
        
        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
            [[MDHRouter sharedInstance].navigationControllerStack.topViewController presentViewController:vc animated:true completion:nil];
        });
    }
}


//MARK: - ===== HQImageEditViewControllerDelegate
///完成
- (void)editController:(HQImageEditViewController *)vc finishiEditShotImage:(UIImage *)image originSizeImage:(UIImage *)originSizeImage {
    if (self.blockCutImage) {
        self.blockCutImage(image);
    }
    self.blockCutImage = nil;
    [vc dismissViewControllerAnimated:true completion:nil];
    [MMWDHPhotoBrowser free:nil];
    //[vc.navigationController popViewControllerAnimated:true];
}
- (void)editControllerDidClickCancel:(HQImageEditViewController *)vc {
    self.blockCutImage = nil;
    [vc dismissViewControllerAnimated:true completion:nil];
    [MMWDHPhotoBrowser free:nil];
    //[vc.navigationController popViewControllerAnimated:true];
}

@end




/// - ==== 图片 视频的编辑管理者
@interface MDHPhotoVideoEditManager ()
<
LFPhotoBrowserDelegate,
LFPhotoBrowserDownloadDelegate,
LFPhotoEditingControllerDelegate,
LFVideoEditingControllerDelegate
>

///相册的管理者
@property (nonatomic, strong, readwrite) HXPhotoManager * manager;
@property (strong, nonatomic) HXPhotoModel *beforePhotoModel;
@property (strong, nonatomic) HXPhotoModel *beforeVideoModel;
//@property (strong, nonatomic) HXDatePhotoToolManager *toolManager;

@end

@implementation MDHPhotoVideoEditManager

///初始化数据
+ (MDHPhotoVideoEditManager *)manager:(HXPhotoManager *)manager {
    return [[MDHPhotoVideoEditManager alloc] initWithManager:manager];
}

- (instancetype)initWithManager:(HXPhotoManager *)ma {
    self = [super init];
    if (self) {
        self.manager = ma;
        ///是否可以编辑 及 使用第三方的框架 进行替换 编辑界面
        ma.configuration.photoCanEdit = YES;
        ma.configuration.videoCanEdit = YES;
        ma.configuration.replacePhotoEditViewController = YES;
        ma.configuration.replaceVideoEditViewController = YES;
        
        __weak typeof(self) weakSelf = self;
        //@weakify(self);
        ma.configuration.shouldUseEditAsset = ^(UIViewController *viewController, BOOL isOutside, HXPhotoManager *manager, HXPhotoModel *beforeModel) {
            @autoreleasepool {
                MDHPhotoVideoEditManager * strongSelf = weakSelf;
                if (strongSelf == nil) {
                    strongSelf = self;
                }
                //@strongify(self);
                if (beforeModel.subType == HXPhotoModelMediaSubTypePhoto) {
                    strongSelf.beforePhotoModel = beforeModel;
                    if (beforeModel.type == HXPhotoModelMediaTypeCameraPhoto) {
                        LFPhotoEditingController *lfPhotoEditVC = [[LFPhotoEditingController alloc] init];
                        lfPhotoEditVC.oKButtonTitleColorNormal = manager.configuration.themeColor;
                        lfPhotoEditVC.cancelButtonTitleColorNormal = manager.configuration.themeColor;
                        
                        lfPhotoEditVC.delegate = strongSelf;
                        if ([beforeModel.tempAsset isKindOfClass:[LFPhotoEdit class]]) {
                            lfPhotoEditVC.photoEdit = beforeModel.tempAsset;
                        }else {
                            lfPhotoEditVC.editImage = beforeModel.previewPhoto;
                        }
                        HXCustomNavigationController *nav = [[HXCustomNavigationController alloc] initWithRootViewController:lfPhotoEditVC];
                        nav.modalPresentationStyle = UIModalPresentationOverFullScreen;
                        [viewController presentViewController:nav animated:true completion:nil];
                    }else {
                        [viewController.view hx_showLoadingHUDText:nil];
                        [beforeModel requestImageDataStartRequestICloud:nil progressHandler:nil success:^(NSData *imageData, UIImageOrientation orientation, HXPhotoModel *model, NSDictionary *info) {
                            [viewController.view hx_handleLoading];
                            UIImage *image = [UIImage imageWithData:imageData];
                            if (image.imageOrientation != UIImageOrientationUp) {
                                image = [image hx_normalizedImage];
                            }
                            LFPhotoEditingController *lfPhotoEditVC = [[LFPhotoEditingController alloc] init];
                            lfPhotoEditVC.oKButtonTitleColorNormal = manager.configuration.themeColor;
                            lfPhotoEditVC.cancelButtonTitleColorNormal = manager.configuration.themeColor;
                            
                            lfPhotoEditVC.delegate = strongSelf;
                            if ([beforeModel.tempAsset isKindOfClass:[LFPhotoEdit class]]) {
                                lfPhotoEditVC.photoEdit = beforeModel.tempAsset;
                            }else {
                                lfPhotoEditVC.editImage = image;
                            }
                            HXCustomNavigationController *nav = [[HXCustomNavigationController alloc] initWithRootViewController:lfPhotoEditVC];
                            nav.modalPresentationStyle = UIModalPresentationOverFullScreen;
                            [viewController presentViewController:nav animated:true completion:nil];
                        } failed:^(NSDictionary *info, HXPhotoModel *model) {
                            [viewController.view hx_handleLoading];
                            [viewController.view hx_showImageHUDText:@"资源获取失败!"];
                        }];
                    }
                }else {
                    strongSelf.beforeVideoModel = beforeModel;
                    if (beforeModel.type == HXPhotoModelMediaTypeCameraVideo) {
                        LFVideoEditingController *lfVideoEditVC = [[LFVideoEditingController alloc] init];
                        lfVideoEditVC.delegate = strongSelf;
                        lfVideoEditVC.minClippingDuration = 3.f;
                        if ([beforeModel.tempAsset isKindOfClass:[LFVideoEdit class]]) {
                            lfVideoEditVC.videoEdit = beforeModel.tempAsset;
                        } else {
                            [lfVideoEditVC setVideoURL:beforeModel.videoURL placeholderImage:beforeModel.tempImage];
                        }
                        HXCustomNavigationController *nav = [[HXCustomNavigationController alloc] initWithRootViewController:lfVideoEditVC];
                        nav.modalPresentationStyle = UIModalPresentationOverFullScreen;
                        [viewController presentViewController:nav animated:true completion:nil];
                    }else {
                        [viewController.view hx_showLoadingHUDText:nil];
                        [beforeModel requestAVAssetStartRequestICloud:nil progressHandler:nil success:^(AVAsset *avAsset, AVAudioMix *audioMix, HXPhotoModel *model, NSDictionary *info) {
                            
                            [viewController.view hx_handleLoading];
                            if ([avAsset isKindOfClass:[AVURLAsset class]]) {
                                NSURL *video = [(AVURLAsset *)avAsset URL];
                                
                                LFVideoEditingController *lfVideoEditVC = [[LFVideoEditingController alloc] init];
                                lfVideoEditVC.delegate = strongSelf;
                                lfVideoEditVC.minClippingDuration = 5.f;
                                if ([beforeModel.tempAsset isKindOfClass:[LFVideoEdit class]]) {
                                    lfVideoEditVC.videoEdit = beforeModel.tempAsset;
                                } else {
                                    [lfVideoEditVC setVideoURL:video placeholderImage:[UIImage hx_thumbnailImageForVideo:video atTime:0.1f]];
                                }
                                HXCustomNavigationController *nav = [[HXCustomNavigationController alloc] initWithRootViewController:lfVideoEditVC];
                                nav.modalPresentationStyle = UIModalPresentationOverFullScreen;
                                [viewController presentViewController:nav animated:true completion:nil];
                            }else {
                                /*[strongSelf.toolManager writeSelectModelListToTempPathWithList:@[beforeModel] requestType:1 success:^(NSArray<NSURL *> *allURL, NSArray<NSURL *> *photoURL, NSArray<NSURL *> *videoURL) {
                                    [viewController.view hx_handleLoading];
                                    NSURL *video = videoURL.firstObject;
                                    
                                    LFVideoEditingController *lfVideoEditVC = [[LFVideoEditingController alloc] init];
                                    lfVideoEditVC.delegate = strongSelf;
                                    lfVideoEditVC.minClippingDuration = 5.f;
                                    if ([beforeModel.tempAsset isKindOfClass:[LFVideoEdit class]]) {
                                        lfVideoEditVC.videoEdit = beforeModel.tempAsset;
                                    } else {
                                        [lfVideoEditVC setVideoURL:video placeholderImage:[UIImage hx_thumbnailImageForVideo:video atTime:0.1f]];
                                    }
                                    HXCustomNavigationController *nav = [[HXCustomNavigationController alloc] initWithRootViewController:lfVideoEditVC];
                                    nav.modalPresentationStyle = UIModalPresentationOverFullScreen;
                                    [viewController presentViewController:nav animated:true completion:nil];
                                } failed:^{
                                    [viewController.view hx_handleLoading];
                                    [viewController.view hx_showImageHUDText:@"资源获取失败!"];
                                }];*/
                            }
                        } failed:^(NSDictionary *info, HXPhotoModel *model) {
                            [viewController.view hx_handleLoading];
                            [viewController.view hx_showImageHUDText:@"资源获取失败!"];
                        }];
                    }
                }
            }
        };
    }
    return self;
}

- (void)lf_PhotoEditingController:(LFPhotoEditingController *)photoEditingVC didFinishPhotoEdit:(LFPhotoEdit *)photoEdit {
    //[photoEditingVC.navigationController setNavigationBarHidden:NO];
    
    HXPhotoModel *model = [HXPhotoModel photoModelWithImage:photoEdit.editPreviewImage];
    model.tempAsset = photoEdit;
    if (photoEditingVC.navigationController.viewControllers.count > 1) {
        [photoEditingVC.navigationController popViewControllerAnimated:NO];
    }else {
        [photoEditingVC dismissViewControllerAnimated:NO completion:nil];
    }
    
    self.manager.configuration.usePhotoEditComplete(self.beforePhotoModel, model);
}

- (void)lf_PhotoEditingController:(LFPhotoEditingController *)photoEditingVC didCancelPhotoEdit:(LFPhotoEdit *)photoEdit {
    //[photoEditingVC.navigationController setNavigationBarHidden:NO];
    
    if (photoEditingVC.navigationController.viewControllers.count > 1) {
        [photoEditingVC.navigationController popViewControllerAnimated:NO];
    }else {
        [photoEditingVC dismissViewControllerAnimated:NO completion:nil];
    }
}

- (void)lf_VideoEditingController:(LFVideoEditingController *)videoEditingVC didCancelPhotoEdit:(LFVideoEdit *)videoEdit {
    //[videoEditingVC.navigationController setNavigationBarHidden:NO];
    
    if (videoEditingVC.navigationController.viewControllers.count > 1) {
        [videoEditingVC.navigationController popViewControllerAnimated:NO];
    }else {
        [videoEditingVC dismissViewControllerAnimated:NO completion:nil];
    }
}
- (void)lf_VideoEditingController:(LFVideoEditingController *)videoEditingVC didFinishPhotoEdit:(LFVideoEdit *)videoEdit {
    //[videoEditingVC.navigationController setNavigationBarHidden:NO];
    
    HXPhotoModel *model = [HXPhotoModel photoModelWithVideoURL:videoEdit.editFinalURL];
    model.tempAsset = videoEdit;
    
    if (videoEditingVC.navigationController.viewControllers.count > 1) {
        [videoEditingVC.navigationController popViewControllerAnimated:NO];
    }else {
        [videoEditingVC dismissViewControllerAnimated:NO completion:nil];
    }
    
    self.manager.configuration.useVideoEditComplete(self.beforeVideoModel, model);
}

@end

